< back index next >

Read EMV

File Structure

The files of a smart card have a tree structure. The first file is the Master File (MF). The MF has one or more Application Definition Files (ADF). Inside of an ADF are Applicaton Elementary Files (AEF) that contain data.
You can quickly select an ADF with the Application Identifier (AID). Within an ADF you can select AEF with the Short File Identifier (SFI).

APDU - Application Protocol Data Unit

After the reset, the communication between terminal and card works with APDUs.

Command APDU

The terminal sends a command APDU to the card. This command has a mandatory header and an optional body.

CLA INS P1 P2 Lc Data Le
Header Trailer

Field Description
CLA Class byte
0x00
INS Instruction byte
0xA4:Select Command
0xB2:Read Record Command
P1 Parameter 1 byte
The function is dependent on INS.
P2 Parameter 2 byte
The function is dependent on INS.
Lc Number of data bytes send to the card.
The value of Lc will be calculated by the terminal. You don't have to state this parameter.
Data Data byte
Le Number of data bytes expected in the response. If Le is 0x00, 256 bytes are expected.

Response APDU

The card will execute the command and send a response APDU back to the terminal. The response APDU has an optional body consisting of data and a mandatory trailer with two status bytes "SW1" and "SW2". SW1 and SW2 result in a status word (SW). If the status word has the value 0x9000 (SW1 = 0x90, SW2=0x00), the command was successful.

Data SW 1 SW 2
Body Trailer

Case 1 to 4

There are four cases of APDU:

Case 1
Command: Header
Response:Trailer
Case 2
Command: Header + Le
Response:Data + Trailer
Case 3
Command: Header + Data
Response: Trailer
Case 4
Command: Header + Data + Le
Response: Data + Trailer

Read EMV Script

To read all data from the card, we use the script contained in the following section:

try	
{
	var card = new Card(_scsh3.reader);
	card.reset(Card.RESET_COLD);
	
	var aid = new ByteString("A0000000041010", HEX); // MC
//	var aid = new ByteString("A0000000031010", HEX); // VISA
	
//	var aid = new ByteString("1PAY.SYS.DDF01", ASCII);



	var fcp = card.sendApdu(0x00, 0xA4, 0x04, 0x00, aid, 0x00, [0x9000]);
	
	print("FCP returned in SELECT: ", new ASN1(fcp));
	
	for (var sfi = 1; sfi <= 31; sfi++) 
	{
		for (var rec = 1; rec <= 16; rec++) 
		{
			var tlv = card.sendApdu(0x00, 0xB2, rec, (sfi << 3) | 4, 0x00);
			if (card.SW == 0x9000) 
			{
				print("SFI " + sfi.toString(16) + " record #" + rec);
				try	
				{
					var asn = new ASN1(tlv);
					print(asn);
				}
				catch(e) 
				{
					print(tlv.toString(HEX));
				}
			}
		}
	}
}

catch(e) 
{
	print("Exception reading from Credit Card Application: " + e.toString());
}

Line 06
This script works either with Mastercard or VISA because both cards are using different AIDs. You'll need to activate the AID that matches your card.

Line 13
To read the card's data we have to choose a direction. We'll do this with a select command. Therefor we use the case 4 command of card.sendApdu():
Here you get a list of parameters of the select command:

Data byte with the directory name
Parameter Description
0x00 Class byte
0xA4 Instruction byte
Select Command
0x04 Parameter 1 byte
Select a directory by name.
0x00 Parameter 2 byte
In general P2 is set to 0x00 when you write the complete AID Name.
aid
0x00 Le byte
It is set to 0x00 so you can get in the response 256 bytes.
[0x9000] Array of acceptable SW1/SW2 return codes

Line 17
Now we create a loop that starts with the first AEF and ends with No 31.

Line 19
In a second loop the rec number of every AEF will be worked out from 1 to 16.

Line 21
With the Read Record Command of "card.sendApdu()" we can get the data to the object "tlv".

Parameter Description
0x00 Class byte
0xB2 Instruction byte
Read Record Command
rec Parameter 1 byte. It contains the record number.
(sfi << 3) | 4 Parameter P2 byte. The first 5 bits containing the SFI and the last three bits are set to 1,0,0 and that means P1 is a record number.
To get the P2 parameter, the SFI will be shift three bits to the left and combinated with a '4'
e.g.
00000001
00001000 <<3
00000100 | 4
00001100 = 0x0C
0x00 Le byte. It is '00' so 256 bytes are expected.

Line 22
If the statusword has the value 0x9000 the command was successful and the tlv object will be printed out.

< back index next >